package boardgamer.yavalath.client;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.text.Html;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import boardgamer.common.client.AbstractActivity;
import boardgamer.common.client.Logger;
import boardgamer.spammer.Ads;
import boardgamer.spammer.AdsPrompt;
import boardgamer.yavalath.R;
import boardgamer.yavalath.client.preference.YavalathPreference;
import boardgamer.yavalath.client.resources.CommonDialogHandler;
import boardgamer.yavalath.client.resources.ImageHandler;
import boardgamer.yavalath.client.resources.SoundHandler;
import boardgamer.yavalath.client.resources.StringHandler;
import com.google.ads.AdRequest;
import com.google.ads.AdView;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;

import static android.view.Menu.NONE;
import static boardgamer.yavalath.client.YavalathActivity.MenuButton.M_ABOUT;
import static boardgamer.yavalath.client.YavalathActivity.MenuButton.M_ADS;
import static boardgamer.yavalath.client.YavalathActivity.MenuButton.M_FEEDBACK;
import static boardgamer.yavalath.client.YavalathActivity.MenuButton.M_SETTINGS;
import static boardgamer.yavalath.client.YavalathActivity.MenuButton.M_SHARE;

/**
 * This class needs to properly handle the lifecycle explained here
 * http://developer.android.com/reference/android/app/Activity.html
 */
public class YavalathActivity extends AbstractActivity<MainView> {

  private static final int ADS_DELAY_SHOW_COUNT = 25;

  private Intent feedbackChooser;
  private Intent shareChooser;
  private AdView adView;

  public YavalathActivity() {
    super(R.layout.game, R.id.viewContainer);
  }

  @Override
  public void onCreate(Bundle savedInstanceState) {
    // TODO: These two must be handled in a special way
    // initialize handlers and screen properties.
    initializeHandlers();

    super.onCreate(savedInstanceState);
  }

  @Override
  protected MainView createView() {
    return new MainView(this);
  }

  @Override
  protected void handleUpdate(int elapsedTime) { }

  @Override
  protected void handleCreate(Bundle savedInstanceState) {
    Logger.logMethod();

    // initialize views
    initializeAdView();
    view.setGameThread(gameThread);

    // initialize settings and intents
    Settings.initialize(this);
    createFeedbackIntent();
    createShareIntent();
  }

  @Override
  protected void handleSaveInstanceState(Bundle outState) { }

  @Override
  protected void handleStart() {
    Logger.logMethod();
  }

  @Override
  protected void handleReady() {
    if (Version.SHOW_ADS.isEnabled()) {
      showAds();
    }
  }

  @Override
  protected void handleStop() {
    Logger.logMethod();
  }

  @Override
  protected void handleResume() {
    Logger.logMethod();
    view.getCurrentScreen().onResume();
  }

  @Override
  protected void handleRestart() { }

  @Override
  protected void handlePause() {
    Logger.logMethod();

    // Save state
    if (Version.SHOW_ADS.isEnabled()) {
      AdsPrompt.instance().save();
    }
  }

  @Override
  protected void handleDestroy() {
    Logger.logMethod();

    // destroy adview
    adView.destroy();
  }

  private void initializeHandlers() {
    ImageHandler.initialize(this, SharedObjects.instance().getFontHandler());
    SoundHandler.initialize(this);
    StringHandler.initialize(this);
    RenderHelper.initialize(ImageHandler.tile);
    CommonDialogHandler.initialize();
    Navigator.initialize(this);
  }

  private void initializeAdView() {
    if (Version.SHOW_ADS.isEnabled()) {
      AdsPrompt.initialize(this, ADS_DELAY_SHOW_COUNT);
    }

    adView = (AdView) this.findViewById(R.id.adView);
    if (SharedObjects.instance().getProFeatures().isEnabled()) {
      adView.setVisibility(View.GONE);
    } else {
      adView.setVisibility(View.VISIBLE);
      adView.loadAd(new AdRequest());
    }
  }

  private void createFeedbackIntent() {
    Intent feedbackIntent = new Intent(Intent.ACTION_SENDTO);
    feedbackIntent.setData(Uri.parse("mailto:board.gamer.dev@gmail.com"));
    feedbackIntent.putExtra(Intent.EXTRA_SUBJECT, "Yavalath Feedback");
    feedbackChooser = Intent.createChooser(feedbackIntent, "Give feedback via");
  }

  private void createShareIntent() {
    Intent sharingIntent = new Intent(Intent.ACTION_SEND);
    sharingIntent.setType("text/plain");
    sharingIntent.putExtra(Intent.EXTRA_SUBJECT, "Yavalath");
    sharingIntent.putExtra(Intent.EXTRA_TEXT, "Play Yavalath NOW!");
    shareChooser = Intent.createChooser(sharingIntent, "Give feedback via");
  }

  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    switch (keyCode) {
      case KeyEvent.KEYCODE_BACK:
        view.back();
        return false;
      case KeyEvent.KEYCODE_VOLUME_DOWN:
        SoundHandler.audioManager.adjustStreamVolume(
            AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
        return true;
      case KeyEvent.KEYCODE_VOLUME_UP:
        SoundHandler.audioManager.adjustStreamVolume(
            AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
        return true;
    }

    return keyCode != KeyEvent.KEYCODE_MENU;
  }

  //---------------------------------------
  // Handle Menu Button
  //---------------------------------------
  protected enum MenuButton {
    M_RESTART(1),
    M_SETTINGS(2),
    M_QUIT(3),
    M_SHARE(4),
    M_FEEDBACK(5),
    M_ABOUT(6),
    M_GAMEOVER(7),
    M_ADS(8),
    M_COMING_SOON(9);

    private int buttonId;
    private MenuButton(int buttonId) {
      this.buttonId = buttonId;
    }

    public int getButtonId() {
      return buttonId;
    }
    
    public static MenuButton fromButtonId(final int buttonId) {
      return Iterables.find(ImmutableList.copyOf(MenuButton.values()), new Predicate<MenuButton>() {
        @Override
        public boolean apply(MenuButton o) {
          return o.getButtonId() == buttonId;
        }
      });
    }
  }

  @Override
  protected Dialog onCreateDialog(int id) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    switch (MenuButton.fromButtonId(id)) {
      case M_SETTINGS:
        return null;
      case M_ABOUT:
        return createAboutDialog(builder);
      case M_ADS:
        return createAdsDialog(builder);
      case M_COMING_SOON:
        return createComingSoonDialog(builder);
      default:
        return null;
    }
  }

  public void showComingSoonDialog() {
    showDialog(MenuButton.M_COMING_SOON.getButtonId());
  }
  
  private Dialog createComingSoonDialog(final AlertDialog.Builder builder) {
    builder.setMessage("This feature is coming soon!");
    return builder.create();
  }

  private Dialog createAdsDialog(final AlertDialog.Builder builder) {
    final Ads ads = AdsPrompt.instance().getAds();

    if (ads == null) {
      return null;
    }

    Context context = getApplicationContext();
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(LAYOUT_INFLATER_SERVICE);
    View adsDialog = inflater.inflate(R.layout.ads, null /* viewRoot */);

    ((ImageView) adsDialog.findViewById(R.id.adsLogo)).setImageBitmap(ads.getAdsLogo());
    TextView textView = ((TextView) adsDialog.findViewById(R.id.adsText));
    textView.setText(ads.getPromoText());
    textView.setTextSize(16f);

    builder.setView(adsDialog);
    builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialogInterface, int i) {
        dialogInterface.dismiss();
        startActivity(ads.getMarketIntent());
      }
    });

    builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialogInterface, int i) {
        dialogInterface.dismiss();
      }
    });

    return builder.create();
  }

  private Dialog createAboutDialog(AlertDialog.Builder builder) {
    Context mContext = getApplicationContext();
    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
    View aboutScreen = inflater.inflate(R.layout.about, null /* viewRoot */);

    TextView fullNameView = (TextView) aboutScreen.findViewById(R.id.aboutFullName);
    fullNameView.setText(StringHandler.instance().aboutFullName);
    fullNameView.setTextSize(18f);
    fullNameView.setTypeface(ImageHandler.headingFont);

    TextView disclaimerView = (TextView) aboutScreen.findViewById(R.id.aboutDisclaimer);
    disclaimerView.setText(Html.fromHtml(StringHandler.instance().aboutDisclaimerHtml));
    disclaimerView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        startActivity(new Intent(Intent.ACTION_VIEW, StringHandler.instance().disclaimerUrl));
      }
    });
    disclaimerView.setTextSize(16f);

    TextView feedbackView = (TextView) aboutScreen.findViewById(R.id.aboutFeedback);
    feedbackView.setText(Html.fromHtml(StringHandler.instance().aboutFeedbackHtml));
    feedbackView.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        startActivity(feedbackChooser);
      }
    });
    feedbackView.setTextSize(16f);

    TextView releaseNotesView = (TextView) aboutScreen.findViewById(R.id.aboutReleaseNotes);
    releaseNotesView.setText(Html.fromHtml(StringHandler.instance().aboutReleaseNotesHtml));
    releaseNotesView.setTextSize(16f);

    builder.setView(aboutScreen);
    return builder.create();
  }

  public void showAds() {
    runOnUiThread(new Runnable() {

      @Override
      public void run() {
        removeDialog(M_ADS.getButtonId()); // reset dialog state
        showDialog(M_ADS.getButtonId());
      }
    });
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (MenuButton.fromButtonId(item.getItemId())) {
      case M_RESTART:
      case M_SETTINGS:
        startActivity(new Intent(getBaseContext(), YavalathPreference.class));
        return true;
      case M_QUIT:
      case M_ABOUT:
        showDialog(item.getItemId());
        return true;
      case M_SHARE:
        startActivity(shareChooser);
        return true;
      case M_FEEDBACK:
        startActivity(feedbackChooser);
        return true;
    }
    return false;
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    menu.clear();
    menu.add(NONE, M_SETTINGS.getButtonId(), NONE, "Settings")
        .setIcon(android.R.drawable.ic_menu_preferences);
    menu.add(NONE, M_FEEDBACK.getButtonId(), NONE, "Feedback")
        .setIcon(android.R.drawable.ic_menu_send);
    menu.add(NONE, M_SHARE.getButtonId(), NONE, "Share")
        .setIcon(android.R.drawable.ic_menu_share);
    menu.add(NONE, M_ABOUT.getButtonId(), NONE, "About")
        .setIcon(android.R.drawable.ic_menu_info_details);
    return true;
  }
}